﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace PlutoStudio.Web.Mvc.Html
{
    public static class InputExtensions
    {
        /// <summary>
        /// Hidden框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static MvcHtmlString Hidden<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            return Input<TModel, TProperty>(htmlHelper, expression, InputType.Hidden, null, false);
        }

        /// <summary>
        /// 密码输入框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="ReadOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString Password<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null, bool ReadOnly = false)
        {
            return Input<TModel, TProperty>(htmlHelper, expression, InputType.Password, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), ReadOnly);
        }

        /// <summary>
        /// 密码输入框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="ReadOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString Password<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes, bool ReadOnly = false)
        {
            return Input<TModel, TProperty>(htmlHelper, expression, InputType.Password, htmlAttributes, ReadOnly);
        }

        /// <summary>
        /// 普通输入框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="ReadOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString TextBox<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null, bool ReadOnly = false)
        {
            return Input<TModel, TProperty>(htmlHelper, expression, InputType.Text, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), ReadOnly);
        }

        /// <summary>
        /// 普通输入框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="ReadOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString TextBox<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes, bool ReadOnly = false)
        {
            return Input<TModel, TProperty>(htmlHelper, expression, InputType.Text, htmlAttributes, ReadOnly);
        }

        /// <summary>
        /// 复选输入框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="ReadOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString CheckBox<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string title=null, object htmlAttributes = null, bool ReadOnly = false)
        {
            return Input<TModel, TProperty>(htmlHelper, expression, InputType.CheckBox, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), ReadOnly, title: title);
        }
 
        /// <summary>
        /// 复选输入框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="ReadOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString CheckBox<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes,string title=null, bool ReadOnly = false)
        {
            return Input<TModel, TProperty>(htmlHelper, expression, InputType.CheckBox, htmlAttributes, ReadOnly,title:title);
        }

        /// <summary>
        /// 开关输入框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="ReadOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString SwitchBox<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null, bool ReadOnly = false)
        {
            return SwitchBox<TModel, TProperty>(htmlHelper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), ReadOnly);
        }

        /// <summary>
        /// 开关输入框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="ReadOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString SwitchBox<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes, bool ReadOnly = false)
        {
            return Input<TModel, TProperty>(htmlHelper, expression, InputType.CheckBox, htmlAttributes, ReadOnly, "ace-switch");
        }

        /// <summary>
        /// 单选输入框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="ReadOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString RadioInput<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null, bool ReadOnly = false)
        {
            return Input<TModel, TProperty>(htmlHelper, expression, InputType.Radio, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), ReadOnly);
        }

        /// <summary>
        /// 单选输入框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="ReadOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString RadioInput<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes, bool ReadOnly = false)
        {
            return Input<TModel, TProperty>(htmlHelper, expression, InputType.Radio, htmlAttributes, ReadOnly);
        }

        private static MvcHtmlString Input<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, InputType inputType, IDictionary<string, object> htmlAttributes, bool ReadOnly = false,string @class=null,string title=null)
        {
            string value = "";
            if (htmlHelper.ViewData.Model != null)
                value = expression.Compile()(htmlHelper.ViewData.Model).ToSafeString();
            if (ReadOnly == true)
                return MvcHtmlString.Create(value.ToSafeString());
            string name = ExpressionHelper.GetExpressionText(expression);

            TagBuilder tagBuilder = new TagBuilder("input");

            tagBuilder.Attributes["type"] = inputType.ToSafeString();
            tagBuilder.MergeAttribute("name", name);
            tagBuilder.MergeAttribute("id", name);

            tagBuilder.MergeAttributes(htmlAttributes, true);

            if (inputType == InputType.CheckBox || inputType == InputType.Radio)
            {
                bool selected = value.ToBool();
                if (selected)
                    tagBuilder.Attributes["checked"] = "checked";
                tagBuilder.Attributes["value"] = "true";
                tagBuilder.AddCssClass("ace");
            }
            else
            {
                tagBuilder.Attributes["value"] = value;
                tagBuilder.AddCssClass("form-control");
            }
            tagBuilder.AddCssClass(@class);
            string result = tagBuilder.ToString(TagRenderMode.SelfClosing);
            if (inputType == InputType.CheckBox || inputType == InputType.Radio)
                result += "<span class=\"lbl\">"+title+"</span><input type=\"hidden\" name=\"" + name + "\" value=\"false\"/>";
            return MvcHtmlString.Create(result);
        }

        /// <summary>
        /// TextArea
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="readOnly"></param>
        /// <returns></returns>
        public static MvcHtmlString TextArea<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null, bool readOnly = false)
        {
            object value = "";
            if (htmlHelper.ViewData.Model != null)
                value = expression.Compile()(htmlHelper.ViewData.Model);
            if (readOnly == true)
                return MvcHtmlString.Create(value.ToSafeString());
            string name = ExpressionHelper.GetExpressionText(expression);

            TagBuilder tagBuilder = new TagBuilder("textarea");
            if (value != null)
                tagBuilder.InnerHtml = value.ToSafeString();
            tagBuilder.MergeAttribute("name", name);
            tagBuilder.MergeAttribute("id", name);
            tagBuilder.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), true);
            tagBuilder.AddCssClass("form-control");

            return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
        }
    }
}
